﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SuperDeepZoom
{
    /// <summary>
    /// The fly through overlay list item content control. This control is templatable.
    /// Allows customisation of the actual fly through lines.
    /// </summary>
    [TemplatePart(Name = "FlyThroughRoot", Type = typeof(Panel))]
    public class FlyThroughOverlayItem : ContentControl
    {
        Panel root;
        RotateTransform rotateTransform = null;

        FlyThroughOverlaySegment currentSegment;

        public FlyThroughOverlayItem()
        {
            DefaultStyleKey = typeof(FlyThroughOverlayItem);
        }

        protected override void OnContentChanged(object oldContent, object newContent)
        {
            if (currentSegment != null)
            {
                currentSegment.PropertyChanged -= new System.ComponentModel.PropertyChangedEventHandler(segment_PropertyChanged);
            }

            if (newContent is FlyThroughOverlaySegment)
            {
                currentSegment = newContent as FlyThroughOverlaySegment;
                currentSegment.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(segment_PropertyChanged);
                updateArrangement();
            }

            base.OnContentChanged(oldContent, newContent);
        }        

        public override void OnApplyTemplate()
        {
            FlyThroughRoot = GetTemplateChild("FlyThroughRoot") as Panel;
            updateArrangement();
            base.OnApplyTemplate();
        }

        void updateArrangement()
        {
            if (rotateTransform != null && currentSegment != null)
            {
                //the angle is so the control points in the correct direction (between the start and finish points)
                rotateTransform.Angle = currentSegment.Angle;
                
                //the width is so the control spans the distance between the start and finish points
                this.Width = currentSegment.Length;

                //The cavas top and left set the control to start at the correct point on the screen
                SetValue(Canvas.TopProperty, currentSegment.Origin.Y);
                SetValue(Canvas.LeftProperty, currentSegment.Origin.X);
            }
        }       

        void initRootElement()
        {
            if (FlyThroughRoot != null)
            {
                //Ensure the transform origin is set to 0,0 so it pivots off the left edge
                FlyThroughRoot.RenderTransformOrigin = new Point(0, .5);

                if (FlyThroughRoot.RenderTransform != null)
                {
                    //First check to see if the transform is rotate tranform
                    if (FlyThroughRoot.RenderTransform is RotateTransform)
                    {
                        rotateTransform = FlyThroughRoot.RenderTransform as RotateTransform;
                    }
                    else if (FlyThroughRoot.RenderTransform is TransformGroup)
                    {
                        //if it is a transform group, scan the children for a rotate transform
                        TransformGroup tg = FlyThroughRoot.RenderTransform as TransformGroup;
                        foreach (Transform t in tg.Children)
                        {
                            if (t is RotateTransform)
                            {
                                rotateTransform = t as RotateTransform;
                            }
                        }
                    }
                }

                //if all else fails then create a rotate transform
                if (rotateTransform == null)
                {
                    rotateTransform = new RotateTransform();
                    FlyThroughRoot.RenderTransform = rotateTransform;
                }
            }
        }

        #region EventHandlers

        void segment_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (FlyThroughRoot != null && currentSegment != null)
            {
                if (e.PropertyName == "Angle")
                {
                    if (rotateTransform != null)
                    {
                        //the angle is so the control points in the correct direction (between the start and finish points)
                        rotateTransform.Angle = currentSegment.Angle;
                    }
                }
                else if (e.PropertyName == "Length")
                {
                    //the width is so the control spans the distance between the start and finish points
                    this.Width = currentSegment.Length;
                }
                else if (e.PropertyName == "Origin")
                {
                    //The cavas top and left set the control to start at the correct point on the screen
                    SetValue(Canvas.TopProperty, currentSegment.Origin.Y);
                    SetValue(Canvas.LeftProperty, currentSegment.Origin.X);
                }                
            }
        }

        #endregion

        #region Properties

        Panel FlyThroughRoot
        {
            get
            {
                return root;
            }
            set
            {
                root = value;
                initRootElement();
            }
        }

        #endregion
    }
}
